package io.gitee.chearnee.fw.sidecar.pool;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author cn
 * @version 1.0
 * @description
 * @date 12/19/2022 11:18 AM
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class SideCarThreadPool {

    private static final int availableProcessors;

    static {
        availableProcessors = Runtime.getRuntime().availableProcessors();
    }

    private static ThreadPoolTaskExecutor taskExecutor;

    public static ThreadPoolTaskExecutor getThreadPool() {
        if (taskExecutor == null) {
            taskExecutor = buildThreadPoolTaskExecutor();
        }
        return taskExecutor;
    }

    private static ThreadPoolTaskExecutor buildThreadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(availableProcessors - 1);
        executor.setMaxPoolSize(availableProcessors * 2);
        executor.setQueueCapacity(50);
        executor.setThreadNamePrefix("side-car-");
        RejectedExecutionHandler rejectedExecutionHandler = BeanUtils
                .instantiateClass(ThreadPoolExecutor.CallerRunsPolicy.class);
        executor.setRejectedExecutionHandler(rejectedExecutionHandler);
        executor.initialize();
        return executor;
    }
}
